/*
Copyright (C) 2008, 2009 Henrik Naess
Copyright (C) 2010 Gerhard Olsson

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using ZoneFiveSoftware.Common.Data.Fitness;
using TrailsPlugin.Integration;

namespace MatrixPlugin.Integration
{
    public class Trails
    {
        //private const string TrailsSettingsClr = "SportTracksTrailsPlugin.Source.Settings";
        private const string TrailsClr = "TrailsPlugin.Data.TrailData";
        //private const string TrailsGuid = "d75393a2-4a95-4fe7-ace2-375ff7338b2c";
        private const string TrailsPlugin = "TrailsPlugin";
        System.Version minVersion = new System.Version( 0, 2, 82, 0 );

        public string CompabilityText
        {
            get
            {
                string result = string.Format(Properties.Resources.TrailsToInstall, minVersion.ToString(), TrailsPlugin);
                Type type;
                System.Version version;
                try
                {
                    type = IntegrationUtility.GetType(TrailsClr, TrailsPlugin, out version);
                    if (type != null)
                    {
                        if (version.CompareTo(minVersion)>=0)
                        {
                            result = string.Format(Properties.Resources.OtherPluginVersion, version.ToString(), TrailsPlugin) + " " +
                                Properties.Resources.TrailsCompatible;
                        }
                        else
                        {
                            result = string.Format(Properties.Resources.OtherPluginVersion, version.ToString(), TrailsPlugin) + " " +
                                string.Format(Properties.Resources.TrailsToInstall, minVersion.ToString(), TrailsPlugin);
                        }
                    }
                }
                catch (Exception)
                {
                }
                return result;
            }
        }

        IList<IList<string[]>> _Trails = null;
        private IList<IList<string[]>> TrailCollection
        {
            get
            {
                if (null == _Trails)
                {
                    _Trails = ListTrails();
                }
                return _Trails;
            }
        }
        public void Refresh()
        {
            _Trails = null;
        }
        public bool TrailsIntegrationEnabeld
        {
            get { return TrailCollection != null; }
        }
        private IList<IList<string[]>> ListTrails()
        {
            IList<IList<string[]>> results = null;
            Type type;
            System.Version version;
            try
            {
                type = IntegrationUtility.GetType(TrailsClr, TrailsPlugin, out version);
                if (type != null && version.CompareTo(minVersion) >= 0)
                {
                    //To use the same type as in Trails, the type must be put in a separate library
                    //Therefore, the info must be extracted using simple types
                    MethodInfo methodInfo = type.GetMethod("ListTrails");
                    results = (IList<IList<string[]>>)methodInfo.Invoke(null, new object[] { });
                }
            }
            catch (Exception e)
            {
                // Log error?
                _Trails = null;
                throw new OtherPlugInException(string.Format(Properties.Resources.OtherPluginExceptionText, 
                    TrailsPlugin + ".dll", Properties.Resources.TrailsPluginName, e) + Environment.NewLine, e);
            }

            //This is not invoked directly by users, no prompt
            //if (type == null)
            //    throw new OtherPlugInException(TrailsExceptionText);

            return results;
        }

        public void AddPositionGroupsFromTrails(ref Dictionary<string, PositionGroup> positions)
        {
            if (null != TrailCollection)
            {
                for (int i = 0; i < TrailCollection.Count; i++)
                {
                    if (TrailCollection[i].Count > 0)
                    {
                        string name = TrailCollection[i][0][0];
                        try
                        {
                            float radius = float.Parse(TrailCollection[i][0][1]);
                            IList<MatrixPoint> points = new List<MatrixPoint>();
                            for (int j = 0; j < TrailCollection[i].Count; j++)
                            {
                                float lat = float.Parse(TrailCollection[i][j][2]);
                                float lng = float.Parse(TrailCollection[i][j][3]);
                                points.Add(new MatrixPoint(TrailCollection[i][j][4], lat, lng, radius));
                            }
                            PositionGroup positionGroup = new PositionGroup(name, points);
                            positions.Add(positionGroup.Name, positionGroup);
                        }
                        catch (Exception e)
                        {
                            string text = TrailCollection[i][0][0] + " " + TrailCollection[i][0][1] + Environment.NewLine;
                            foreach (string[] t in TrailCollection[i])
                            {
                                text += " " + t[2] + " " + t[3] + " " + t[4] + Environment.NewLine;
                            }
                            throw new OtherPlugInException(string.Format(Properties.Resources.TrailsParseException,
                                name, text, e) + Environment.NewLine, e);
                        }
                    }
                }
            }
        }
    }
}